import os
import io
import base64
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from matplotlib.font_manager import FontProperties
from mpl_toolkits.mplot3d import Axes3D
import random
import plotly.graph_objects as go
from bokeh.layouts import column, row as bokeh_row

root_path = os.path.abspath(os.path.join(os.path.dirname(__file__), ""))
parent_path = os.path.dirname(root_path)


def generate_three_dimensional_container_visualization(df,
                                                       container_length=2.352, container_width=12.032,
                                                       container_height=2.385, unique_colors=None,
                                                       filename=0, c_id=0, type=0, from_net=0):
    # 创建3D图
    fig = plt.figure(figsize=(10, 7))
    ax = fig.add_subplot(111, projection='3d')

    # 绘制集装箱
    ax.bar3d(0, 0, 0, container_length, container_width, container_height, alpha=0.1, color='gray')

    # 绘制货物
    handles = []  # 用于存储图例的句柄
    labels = []  # 用于存储图例的标签
    for index, row in df.iterrows():
        if row['rotate'] == 1:
            bar = ax.bar3d(row['x'], row['y'], row['z'], row['l'] / 1000, row['w'] / 1000, row['h'] / 1000, alpha=0.6,
                           color=unique_colors[row['box_type']])
        else:
            bar = ax.bar3d(row['x'], row['y'], row['z'], row['w'] / 1000, row['l'] / 1000, row['h'] / 1000, alpha=0.6,
                           color=unique_colors[row['box_type']])

        # 如果当前货类还没有添加到图例中，则添加
        if row['box_type'] not in labels:
            # 创建代理对象
            proxy = plt.Rectangle((0, 0), 1, 1, fc=unique_colors[row['box_type']], alpha=0.6)
            handles.append(proxy)
            labels.append(row['box_type'])

    # 设置轴标签
    ax.set_xlabel('X ', labelpad=10)
    ax.set_ylabel('Y ', labelpad=20)
    ax.set_zlabel('Z ', labelpad=10)
    # 设置坐标轴范围
    ax.set_xlim([0, container_length])
    ax.set_ylim([0, container_width])
    ax.set_zlim([0, container_height])

    # 设置坐标轴单位长度相同
    ax.set_box_aspect([container_length, container_width, container_height])
    # 设置坐标轴刻度
    ax.set_xticks(np.arange(0, container_length, 0.5))
    ax.set_yticks(np.arange(0, container_width, 1))
    ax.set_zticks(np.arange(0, container_height, 0.5))

    # 增加网格线
    ax.grid(True)

    # 调整视角
    # ax.view_init(elev=20, azim=30)
    font_path = '/usr/share/fonts/SimHei.ttf'
    font_prop = FontProperties(fname=font_path, size=14)
    # 设置图标题
    ax.set_title(f'集装箱{c_id}_型号{type}_装载图', fontproperties=font_prop)

    # 添加图例
    ax.legend(handles, labels, bbox_to_anchor=(1.05, 1), loc='upper left', prop=font_prop)

    if from_net == 0:
        plt.savefig(f'{parent_path}/result/pictures/{filename}/集装箱{c_id}_型号{type}_装载图.png',
                    bbox_inches="tight", dpi=600)
        return None
    else:
        # 将图形保存到内存中的 BytesIO 对象
        img = io.BytesIO()
        plt.savefig(f'{parent_path}/temp/result/pictures/{filename}/集装箱{c_id}_型号{type}_装载图.png',
                    bbox_inches="tight", dpi=600, format='png')
        plt.savefig(img, format='png')
        img.seek(0)
        img_data = base64.b64encode(img.getvalue()).decode()
        return img_data